<template>
  <el-dialog
    :model-value="visible"
    :title="dialogTitle"
    @close="handleClose"
    :before-close="handleBeforeClose"
    destroy-on-close
  >
    <el-form
      :model="menuForm"
      ref="menuFormRef"
      :rules="formRules"
      label-width="100px"
      scroll-to-error
    >
      <el-form-item label="菜单名" prop="name">
        <el-input v-model="menuForm.name" clearable />
      </el-form-item>
      <el-form-item label="路由路径" prop="path">
        <el-input v-model="menuForm.path" clearable />
      </el-form-item>
      <el-form-item label="图标" prop="icon">
        <el-input v-model="menuForm.icon" clearable />
      </el-form-item>
      <el-form-item label="序号" prop="sort">
        <el-input v-model="menuForm.sort" clearable />
      </el-form-item>
      <el-form-item label="类型" prop="type">
        <el-select v-model="menuForm.type" clearable>
          <el-option :value="'0'" :label="'目录'" />
          <el-option :value="'1'" :label="'菜单'" />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="handleClose" :loading="btnLoading">取消</el-button>
      <el-button @click="resetmenuForm" :loading="btnLoading">重置表单</el-button>
      <el-button type="primary" @click="submitForm" :loading="btnLoading">确定</el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue'
import { geMenuFormRules } from '../../user/config/constant'
import { MenuMould } from '@/api/menu/types/index'

const props = defineProps({
  visible: {
    type: Boolean,
    required: true
  },
  currentMenu: {
    type: Object
  },
  dialogTitle: {
    type: String,
    required: true
  },
  //'0'：新增 '1'编辑 '2'仅查看
  dialogType: {
    type: String,
    required: true
  },
  //父菜单的Id - 默认0
  parentId: {
    type: Number,
    required: true
  }
})

// 子组件通知父组件处理
const emit = defineEmits<{
  (e: 'update:visible', visible: boolean): void
  (e: 'submit', menu: MenuMould.IMenuItem, type: string): void
}>()

const menuFormRef = ref()
// 表单校验规则 - 该函数单独抽取到配置文件
const formRules = geMenuFormRules()
const menuForm = ref<MenuMould.IMenuItem>({
  id: '',
  parentId: 0,
  name: '',
  path: '',
  component: '',
  icon: '',
  sort: '',
  type: ''
})

// 没有执行 onMounted -- 在首页就执行了。在打开弹窗时不会执行
watch(
  () => props.visible,
  () => {
    if (props.visible && props.currentMenu?.id) {
      // 新增子菜单 - 赋值parentIp
      if (props.dialogType === '0') {
        menuForm.value.parentId = props.parentId
      } else if (props.dialogType === '1') {
        menuForm.value = { ...props.currentMenu } as MenuMould.IMenuItem
      }
    }
  }
)

// 用来判断是否阻止弹窗关闭 - 可有也可没有。如让用户确认是否已保存数据
const handleBeforeClose = (done: (isConfirm?: boolean) => void) => {
  ElMessageBox.prompt('关闭弹窗前的确认', 'Tip', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPattern: /^(?!\s*$).+/,
    inputErrorMessage: '请填写输入框'
  })
    .then(({ value }) => {
      done()
    })
    .catch(() => {})
}

// 子组件关闭弹窗时的处理
const handleClose = () => {
  // 关闭弹窗
  emit('update:visible', false)

  // 清空表单的数据。避免打开新增弹窗直接回显上次的用户信息
  menuForm.value = {
    id: '',
    parentId: 0,
    name: '',
    path: '',
    component: '',
    icon: '',
    sort: '',
    type: ''
  }

  // 重置表单的校验警告
  menuFormRef.value?.clearValidate()
}

// 重置表单为初始状态
const resetmenuForm = () => {
  menuFormRef.value?.resetFields()
}

// 当前弹窗所有按钮的 loading
const btnLoading = ref(false)
const submitForm = async () => {
  const valid = await menuFormRef.value?.validate()

  if (!valid) {
    // 给用户提示或其他逻辑处理
    return ElMessage.error('表单验证失败，请检查输入')
  }

  if (valid) {
    btnLoading.value = true
    try {
      emit('submit', menuForm.value, props.dialogType)
      handleClose()
    } catch (error) {
    } finally {
      btnLoading.value = false
    }
  }
}

// 暴露方法或属性给父组件 - 需要子组件定义过该方法
defineExpose({})
</script>
